package cc.rengu.oltp.utility.util;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 时间操作工具类
 * Created by 王成 on 2017/11/13.
 */
public class DateUtil {

    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式转换
     *
     * @param date 日期
     * @return 日期字符串
     */
    public static String formatDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN);
        return simpleDateFormat.format(date);
    }

    /**
     * 日期格式转换
     *
     * @param date   日期
     * @param format 格式
     * @return 日期字符串
     */
    public static final String formatDate(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }


    /**
     * 日期字符串格式转换
     *
     * @param srcDateString 日期字符串
     * @param srcFormat     源字符串格式
     * @param dstFormat     目标字符串格式
     * @return 日期字符串
     */
    public static final String dateStringFormatConvert(String srcDateString, String srcFormat, String dstFormat) {
        long dateString = getTimeStamp(srcDateString, srcFormat);
        return getDateByTimeStamp(dateString, dstFormat);
    }

    /**
     * 获取当前系统日期（yyyyMMdd）
     *
     * @return String
     */
    public static String getCurrentDate() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String datetime = sdf.format(date);
        return datetime;
    }

    /**
     * 获取当前系统时间（hhmmss）
     *
     * @return String
     */
    public static String getCurrentTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
        String datetime = sdf.format(date);
        return datetime;
    }

    /**
     * 获取当前格式化时间（yyyy-MM-dd HH:mm:ss）
     *
     * @return String
     */
    public static String getCurrentDateTime(String format) {
        Date date = new Date();
        SimpleDateFormat sdf;
        if (format.isEmpty()) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else {
            sdf = new SimpleDateFormat(format);
        }
        String datetime = sdf.format(date);
        return datetime;
    }

    /**
     * 获取当前时间戳
     *
     * @return long
     */
    public static long getCurrentTimeStamp() {
        return System.currentTimeMillis();
    }

    /**
     * 将时间戳转换成日期格式yyyy-MM-dd HH:mm:ss
     *
     * @param timestamp
     * @return String
     */
    public static String getDateByTimeStamp(long timestamp) {
        if (timestamp != 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = sdf.format(new Date(timestamp));
            return date;
        } else {
            return "";
        }
    }

    /**
     * 将时间戳转换成时间格式为yyyy-MM-dd HH:mm:ss或者yyyy-MM-dd的时间
     *
     * @param timestamp
     * @param format
     * @return String
     */
    public static String getDateByTimeStamp(long timestamp, String format) {
        if (timestamp != 0) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String date = sdf.format(new Date(timestamp));
            return date;
        } else {
            return "";
        }
    }

    /**
     * 将时间字符串转换成时间戳
     *
     * @param datetime
     * @return Long
     */
    public static Long getTimeStamp(String datetime, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date;
        try {
            date = simpleDateFormat.parse(datetime);
            Long timeStamp = date.getTime();
            return timeStamp;
        } catch (Exception e) {

        }
        return 0L;
    }

    /**
     * 将日期字符串转换成日期
     *
     * @param dateString 日期字符串
     * @param format     日期格式
     * @return 日期
     */
    public static Date getDateStamp(String dateString, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateString);
        } catch (Exception e) {

        }
        return date;
    }

    /**
     * 比较两个日期的大小
     *
     * @param baseDate 基准日期
     * @param compDate 比较日期
     * @return 0-相等，小于0-基准日期小到比较日期，大于0-基准日期大于比较日期
     */
    public static int compareDate(String baseDate, String compDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        long longDiffSeconds = 0;
        try {
            Date beginDate = simpleDateFormat.parse(baseDate);
            Date endDate = simpleDateFormat.parse(compDate);
            longDiffSeconds = beginDate.getTime() - endDate.getTime();
        } catch (Exception e) {

            return 0;
        }
        long longDiffDays = longDiffSeconds / 86400000L;
        return Integer.parseInt(Long.toString(longDiffDays));
    }

    /**
     * 根据日期格式比较两个时间的大小
     *
     * @param baseTime 基准时间
     * @param compTime 比较时间
     * @param format   时间格式
     * @return 0-相等，小于0-基准时间小到比较时间，大于0-基准时间大于比较时间
     */
    public static int compareTime(String baseTime, String compTime, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        long longDiffSeconds;
        try {
            Date beginDate = simpleDateFormat.parse(baseTime);
            Date endDate = simpleDateFormat.parse(compTime);
            longDiffSeconds = beginDate.getTime() - endDate.getTime();
        } catch (Exception e) {
            return 0;
        }
        long l = Long.parseLong(Long.toString(longDiffSeconds));
        if (l == 0) {
            return 0;
        } else if (l > 0) {
            return 1;
        } else {
            return -1;
        }

    }

    /**
     * 获取指定天数后的日期
     *
     * @param offset 指定天数
     * @return 指定天数后的日期
     */
    public static String getFutureDay(int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, offset);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    /**
     * 根据基准日期及偏移值计算对应的日期
     *
     * @param baseDate 基准日期
     * @param offset   偏移量
     * @return 偏移量对应的日期
     */
    public static String getBaseDateOffsetDay(String baseDate, int offset) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            Calendar calendar = Calendar.getInstance();
            Date date = simpleDateFormat.parse(baseDate);
            calendar.setTime(date);
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + offset);
            return simpleDateFormat.format(calendar.getTime());
        } catch (ParseException e) {

        }
        return null;
    }

    /**
     * 获取指定月份后的日期
     *
     * @param nextMonth 指定月份
     * @return 指定月份后的日期
     */
    public static String getFutureMonDay(int nextMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, nextMonth);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    /**
     * 根据基础日期获取偏移月份对应的日期
     *
     * @param baseDate 基础日期
     * @param offset   偏移量
     * @return 偏移月份后对应的日期
     */
    public static String getBaseDateOffsetMonth(String baseDate, int offset) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            Calendar calendar = Calendar.getInstance();
            Date date = simpleDateFormat.parse(baseDate);
            calendar.setTime(date);
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + offset);
            return simpleDateFormat.format(calendar.getTime());
        } catch (ParseException e) {

        }
        return null;
    }

    /**
     * 获取指定秒数以前的时间
     *
     * @param seconds 指定的秒数
     * @param format  日期格式
     * @return 以前的时间
     */
    public static String getPrevioustimes(Long seconds, String format) {
        long previoustimes = System.currentTimeMillis() - seconds;
        return getDateByTimeStamp(previoustimes, format);
    }

    /**
     * 计算时间差，精确到毫秒
     *
     * @param startTime 开始时间
     * @param endTime   截止时间
     * @return long 时间差
     **/
    public static long getTimeCost(String startTime, String endTime) {
        return getTimeCost(startTime, endTime, "yyyy-MM-dd HH:mm:ss.SSS");
    }

    /**
     * 计算时间差，精确到毫秒
     *
     * @param startTime 开始时间
     * @param endTime   截止时间
     * @param format    时间格式
     * @return 时间差
     */
    public static long getTimeCost(String startTime, String endTime, String format) {
        SimpleDateFormat dfs = new SimpleDateFormat(format);
        try {
            Date begin = dfs.parse(startTime);
            Date end = dfs.parse(endTime);
            // 得到两者的毫秒数
            return (end.getTime() - begin.getTime());
        } catch (Exception ex) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ex.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            return 0;
        }
    }


    /**
     * 获取指定分钟后的日期
     *
     * @param offset 指定分钟
     * @return 指定分钟后的日期
     */
    public static String getFutureDayTime(int offset, String... format) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, offset);
        if (null != format) {
            return new SimpleDateFormat(format[0]).format(calendar.getTime());
        } else {
            return new SimpleDateFormat("yyyyMMddHHmmss").format(calendar.getTime());
        }
    }

    /**
     * 获取未来指定时间格式的时间字符串
     *
     * @param srcDateTime 起始时间
     * @param format      时间格式
     * @param timeFlag    MS/ms 毫秒； S/s 秒；M/m 分钟；H/h 小时；D/d 天；MH/mh 月；Y/y 年
     * @param time        单位同timeFlag
     * @return 时间
     * @throws ParseException 异常
     */
    public static String getPastOrFutureDayTime(String srcDateTime, String format, String timeFlag, int time) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date srcDateTime1 = simpleDateFormat.parse(srcDateTime);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(srcDateTime1);
        switch (timeFlag) {
            case ("ms"):
            case ("MS"):
                calendar.add(Calendar.MILLISECOND, time);
            case ("S"):
            case ("s"):
                //秒
                calendar.add(Calendar.SECOND, time);
                break;
            case ("M"):
            case ("m"):
                calendar.add(Calendar.MINUTE, time);
                break;
            case ("H"):
            case ("h"):
                calendar.add(Calendar.HOUR_OF_DAY, time);
                break;
            case ("D"):
            case ("d"):
                calendar.add(Calendar.DAY_OF_MONTH, time);
                break;
            case ("MH"):
            case ("mh"):
                calendar.add(Calendar.MONTH, time);
                break;
            case ("Y"):
            case ("y"):
                calendar.add(Calendar.YEAR, time);
                break;
            default:
                calendar.add(Calendar.SECOND, time);
                break;
        }
        Date date = calendar.getTime();
        return simpleDateFormat.format(date);
    }

    /**
     * 校验日期格式
     *
     * @param sDate  日期字符串
     * @param format 日期格式
     * @return true-正确,false-不正确
     */
    public static boolean checkDateFormat(String sDate, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            Date date = simpleDateFormat.parse(sDate);
            return sDate.equals(simpleDateFormat.format(date));
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 获取某月的第1天
     *
     * @param yearMonth 指定年月，格式为YYYYMM，当为空时，返回当月第1天
     * @return 指定月份的第1天
     */
    public static String getFirstDayOfMonth(String... yearMonth) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        if (null != yearMonth && yearMonth[0].length() == 6) {
            int year = Integer.parseInt(yearMonth[0].substring(0, 4));  //年
            int month = Integer.parseInt(yearMonth[0].substring(4, 6)); //月
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month - 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            return simpleDateFormat.format(calendar.getTime());
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            return simpleDateFormat.format(calendar.getTime());
        }
    }

    /**
     * 获取某月的最后1天
     *
     * @param yearMonth 指定年月，格式为YYYYMM，当为空时，返回当月最后天
     * @return 指定月份的最后1天
     */
    public static String getLastDayOfMonth(String... yearMonth) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        if (null != yearMonth && yearMonth[0].length() == 6) {
            int year = Integer.parseInt(yearMonth[0].substring(0, 4));  //年
            int month = Integer.parseInt(yearMonth[0].substring(4, 6)); //月
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month - 1);
            int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            calendar.set(Calendar.DAY_OF_MONTH, lastDay);
            return simpleDateFormat.format(calendar.getTime());
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            return simpleDateFormat.format(calendar.getTime());
        }
    }
}
